#ifndef RENDERCOMPONENTS_H
#define RENDERCOMPONENTS_H

#include "..\src\Game Objects\PaintTypes.h"

namespace RenderComponent {

// Macro to convert windows colors (0 - 255) to OGL colors (0 - 1)
#define WINDOWS_COLOR_TO_OGL_COLOR(r, g, b, a) Color((float)r/255.0f, (float)g/255.0f, (float)b/255.0f, (float)a/255.0f)

// Macro to convert OGL colors (0 - 1) to ogl colors (0 - 255)
#define OGL_COLOR_TO_WINDOWS_COLOR(r, g, b, a) Color((float)r*255.0f, (float)g*255.0f, (float)b*255.0f, (float)a*255.0f)

#define COLOR_EMPTY Color(1.0f, 1.0f, 1.0f, 0.5f)
#define COLOR_WHITE Color(1.0f, 1.0f, 1.0f)
#define COLOR_BLACK Color(0.0f, 0.0f, 0.0f)
#define COLOR_GREY Color(0.25f, 0.25f, 0.25f)
#define COLOR_RED Color(1.0f, 0.0f, 0.0f)
#define COLOR_GREEN Color(0.0f, 1.0f, 0.0f)
#define COLOR_BLUE Color(0.0f, 0.0f, 1.0f)
#define COLOR_YELLOW Color(1.0f, 1.0f, 0.0f)
#define COLOR_ORANGE WINDOWS_COLOR_TO_OGL_COLOR(255, 165, 0, 255)
#define COLOR_PURPLE Color(0.5f, 0.0f, 0.5f)
#define COLOR_VIOLET WINDOWS_COLOR_TO_OGL_COLOR(238, 130, 238, 255)
#define COLOR_INDIGO WINDOWS_COLOR_TO_OGL_COLOR(75, 0, 130, 255)
#define COLOR_MAGENTA Color(0.0f, 1.0f, 0.0f)
#define COLOR_MANILLA WINDOWS_COLOR_TO_OGL_COLOR(244, 225, 174, 255)
#define COLOR_AQUA Color(0.2f, 0.8f, 0.8f)
#define COLOR_MINT Color(0.3f, 0.8f, 0.3f)
#define COLOR_INDIAN_RED Color(0.8f, 0.2f, 0.2f)
#define COLOR_LEMON Color(0.8f, 0.8f, 0.2f)

#define CHOKE_A_BITCH_BLUE COLOR_AQUA

	typedef struct RenderColor
	{
		union
		{
			float v[4];

			struct { vec2 rg; };
			struct { vec3 rgb; };
			struct { vec4 rgba; };

			struct
			{
				float r;
				float g;
				float b;
				float a;
			};
		};

		RenderColor() : r(1.0f), g(1.0f), b(1.0f), a(1.0f) { }
		RenderColor(float _r, float _g, float _b, float _a) : r(_r), g(_g), b(_b), a(_a) { }
		RenderColor(float _r, float _g, float _b) : r(_r), g(_g), b(_b), a(1.0f) { }
		RenderColor(const vec2& _rg) : b(1.0f), a(1.0f) { rg = _rg; }
		RenderColor(const vec3& _rgb) : a(1.0f) { rgb = _rgb; }
		RenderColor(const vec4& _rgba)  { rgba = _rgba; }
		RenderColor(const PaintType& type)
		{
			switch(type)
			{
			case RED:		(*this) = COLOR_INDIAN_RED;	break;
			case GREEN:		(*this) = COLOR_MINT;		break;
			case BLUE:		(*this) = COLOR_AQUA;		break;
			case YELLOW:	(*this) = COLOR_LEMON;		break;
			default:		(*this) = COLOR_WHITE;
			};
		}

		float operator[](int i) const { return v[i]; }
		float& operator[](int i) { return v[i]; }

		RenderColor& operator=(const RenderColor& rhs) 
		{ 
			if(this == &rhs) return *this; 

			r = rhs.r;
			g = rhs.g;
			b = rhs.b;
			a = rhs.a;

			return *this;
		}
		
		RenderColor(const RenderColor& rhs)
		{
			r = rhs.r;
			g = rhs.g;
			b = rhs.b;
			a = rhs.a;
		}

		bool IsTransparent() const { return (a < 1.0f); }
		bool IsInvisible() const { return (a <= 0.0f); }

	} Color;

	inline Color operator!(const Color& rhs) 
	{ 
		Color color = OGL_COLOR_TO_WINDOWS_COLOR(rhs.r, rhs.g, rhs.b, rhs.a);

		color.r = (float)((int)color.r ^ 255);
		color.g = (float)((int)color.g ^ 255);
		color.b = (float)((int)color.b ^ 255);

		return WINDOWS_COLOR_TO_OGL_COLOR(color.r, color.g, color.b, color.a); 
	}

	inline bool operator==(const Color& A, const Color& B) { return (A.rgb == B.rgb); }
	inline bool operator!=(const Color& A, const Color& B) { return (A.rgb != B.rgb) ; }

	// ROY G BIV -- Colors of the rainbow
	static const Color RAINBOW[7] = 
	{ 
		COLOR_RED, 
		COLOR_ORANGE, 
		COLOR_YELLOW, 
		COLOR_GREEN, 
		COLOR_BLUE, 
		COLOR_INDIGO, 
		COLOR_VIOLET 
	};
};

#endif